using System;
using Microsoft.SPOT;
using System.Text;
using System.IO.Ports;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace FEZ_Cobra_Console_Application1
{
    internal class ComPort
    {
        private SerialPort comPort = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
        private Boolean validSentenceReceived = false;

        internal delegate void ProcessComPortDataEventHandler(Byte[] receivedDataBuffer);
        internal static event ProcessComPortDataEventHandler ProcessComPortDataEvent;

        /// <summary>
        /// If the COM port is open, close it.
        /// </summary>		

        internal void CloseComPort()
        {
            try
            {
                if (comPort.IsOpen)
                {
                    comPort.Close();
                }
            }
            catch (System.IO.IOException ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Read received data and fire an event to process the data.		
        /// </summary>		
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                // It's possible to get here when the port is closed, so verify the port is open.

                if (comPort.IsOpen)
                {
                    if (!validSentenceReceived)
                    {
                        Byte[] receivedDataBuffer = new byte[comPort.BytesToRead];
                        Debug.Print(ConvertBase64.ToBase64String(receivedDataBuffer));
                        comPort.Read(receivedDataBuffer, 0, receivedDataBuffer.Length);

                        if (null != ProcessComPortDataEvent)
                            ProcessComPortDataEvent(receivedDataBuffer);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Respond to error events.
        /// </summary>

        private void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            SerialError SerialErrorReceived = e.EventType;

            switch (SerialErrorReceived)
            {
                case SerialError.Frame:
                    Debug.Print("Framing error.");

                    break;
                case SerialError.Overrun:
                    Debug.Print("Character buffer overrun.");

                    break;
                case SerialError.RXOver:
                    Debug.Print("Input buffer overflow.");

                    break;
                case SerialError.RXParity:
                    Debug.Print("Parity error.");

                    break;
                case SerialError.TXFull:
                    Debug.Print("Output buffer full.");
                    break;
            }
        }

        /// <summary>
        /// Open the SerialPort object.		
        /// </summary>		 

        internal bool OpenComPort()
        {
            bool success = false;
            try
            {
                validSentenceReceived = false;

                if (!comPort.IsOpen)
                {
                    comPort.Handshake = Handshake.None;
                    comPort.Open();
                    comPort.DataReceived +=
                        new SerialDataReceivedEventHandler(comPort_DataReceived);
                    comPort.ErrorReceived +=
                        new SerialErrorReceivedEventHandler(comPort_ErrorReceived);
                }
            }
            catch (System.IO.IOException ex)
            {
                Debug.Print(ex.Message);
            }
            return success;
        }

        internal void write(string ss)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(ss);
            comPort.Write(buffer, 0, buffer.Length);
        }
    }		

}
